﻿/*
*      
*          ┌─┐       ┌─┐
*       ┌──┘ ┴───────┘ ┴──┐
*       │                 │
*       │       ───       │
*       │  ─┬┘       └┬─  │
*       │                 │
*       │       ─┴─       │
*       │                 │
*       └───┐         ┌───┘
*           │         │
*           │         │
*           │         │
*           │         └──────────────┐
*           │                        │
*           │                        ├─┐
*           │                        ┌─┘    
*           │                        │
*           └─┐  ┐  ┌───────┬──┐  ┌──┘         
*             │ ─┤ ─┤       │ ─┤ ─┤         
*             └──┴──┘       └──┴──┘ 
*                 神兽保佑 
*                 代码无BUG! 
*  Author shang
*  2022-07-25 星期一 11:16
*/

using Autofac.Annotation;
using Microsoft.Extensions.Configuration;
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Triggers;
using Serilog;
using TS.Common;
using TS.Common.Db;
using TS.Model;

namespace TS.Services;

[Component]
[DisallowConcurrentExecution]
public class HttpResultfulJob : DbContext, IJob
{
    [Autowired] public IConfiguration _Configuration { get; set; }

    [Autowired] public IHttpClientFactory httpClientFactory { get; set; }

    public async Task Execute(IJobExecutionContext context)
    {
        var salt = _Configuration.GetSection("cryptogram").Value;
        string httpMessage = "";
        try
        {
            DateTime dateTime = DateTime.Now;
            AbstractTrigger trigger = (context as JobExecutionContextImpl).Trigger as AbstractTrigger;

            TaskOptions taskOptions = await Db.Queryable<TaskOptions>()
                .Where(x => x.TaskName == trigger.Name && x.GroupName == trigger.Group).FirstAsync();
            if (taskOptions == null)
                taskOptions = await Db.Queryable<TaskOptions>()
                    .Where(x => x.TaskName == trigger.JobName && x.GroupName == trigger.JobGroup).FirstAsync();

            if (taskOptions == null)
            {
                TaskLog log = new TaskLog()
                {
                    group = trigger.Group,
                    taskname = trigger.Name,
                    BeginDate = dateTime.ToString("yyyy-MM-dd HH:mm:ss:fff"),
                    Msg = "未到找作业或可能被移除",
                };
                await Db.Insertable(log).ExecuteCommandAsync();
                return;
            }

            if (string.IsNullOrEmpty(taskOptions.ApiUrl) || taskOptions.ApiUrl == "/")
            {
                TaskLog log = new TaskLog()
                {
                    TaskID = taskOptions.ID,
                    group = trigger.Group,
                    taskname = trigger.Name,
                    BeginDate = dateTime.ToString("yyyy-MM-dd HH:mm:ss:fff"),
                    Msg = "未配置url",
                };
                await Db.Insertable(log).ExecuteCommandAsync();
                return;
            }

            Dictionary<string, string> header = new Dictionary<string, string>();
            if (!string.IsNullOrEmpty(taskOptions.AuthKey)
                && !string.IsNullOrEmpty(taskOptions.AuthValue))
            {
                var datetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                var firstmd5 = taskOptions.AuthValue.Trim().ToMD5();
                var addsalt = (firstmd5 + datetime + salt).ToMD5();
                header.Add(taskOptions.AuthKey.Trim(), addsalt);
                header.Add("datetime", datetime);
            }

            httpMessage = await httpClientFactory.HttpSendAsync(
                taskOptions.RequestType?.ToLower() == "get" ? HttpMethod.Get : HttpMethod.Post,
                taskOptions.ApiUrl,
                header);
            TaskLog logforsucess = new TaskLog()
            {
                TaskID = taskOptions.ID,
                group = trigger.JobGroup,
                taskname = trigger.JobName,
                BeginDate = dateTime.ToString("yyyy-MM-dd HH:mm:ss:fff"),
                EndDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"),
                Msg = httpMessage,
            };
            await Db.Insertable(logforsucess).ExecuteCommandAsync();
            await Db.Updateable<TaskOptions>().Where(x => x.ID == taskOptions.ID)
                .SetColumns(x => new TaskOptions { LastRunTime = DateTime.Now }).ExecuteCommandAsync();
        }
        catch (Exception e)
        {
            Log.Error(e, "");
        }
    }
}